In this part of the course, we will cover the following concepts:
| Objective | Complete |
|---|---|
| Create interactive maps utilizing JSON files | |
| Illustrate adding motion to maps to display spatial data over time | |
| Discuss best practices for highcharter maps |
In order to maximize the efficiency of your workflow, use the box package and encode your directory structure into variables
Let the main_dir be the variable corresponding to your materials folder
data directory inside the materials folder in your environment; hence we will save their path to a data_dir variableplots directory corresponding to plot_dir variablepaste0 command and pass the strings you would like to paste togetherstate.x77 datadatasets librarystate.x77 data'data.frame': 50 obs. of 10 variables:
$ Population: int 3615 365 2212 2110 21198 2541 3100 579 8277 4931 ...
$ Income : int 3624 6315 4530 3378 5114 4884 5348 4809 4815 4091 ...
$ Illiteracy: num 2.1 1.5 1.8 1.9 1.1 0.7 1.1 0.9 1.3 2 ...
$ Life.Exp : num 69 69.3 70.5 70.7 71.7 ...
$ Murder : num 15.1 11.3 7.8 10.1 10.3 6.8 3.1 6.2 10.7 13.9 ...
$ HS.Grad : num 41.3 66.7 58.1 39.9 62.6 63.9 56 54.6 52.6 40.6 ...
$ Frost : int 20 152 15 65 20 166 139 103 11 60 ...
$ Area : int 50708 566432 113417 51945 156361 103766 4862 1982 54090 58073 ...
$ State : chr "Alabama" "Alaska" "Arizona" "Arkansas" ...
$ code : chr "AL" "AK" "AZ" "AR" ...
geoJSON is a JavaScript Object Notation format representing simple geographical features and non-spatial attributesHighcharts has a viewable collection of geoJSON files covering most areas of the worldjsonlite packageRegistered S3 method overwritten by 'quantmod':
method from
as.zoo.data.frame zoo
Highcharts (www.highcharts.com) is a Highsoft software product which is
not free for commercial and Governmental use
hc_middle_x and hc_middle-y coordinates will be used for plottingname and postal-code will be used to create and label the states in the map# To see what metadata is available in the `geo.json`, use `get_data_from_map` function.
geodata = get_data_from_map(US_map)
# Look at only 15 first columns
str(geodata[,1:15])tibble [52 × 15] (S3: tbl_df/tbl/data.frame)
$ hc-group : chr [1:52] "admin1" "admin1" "admin1" "admin1" ...
$ hc-middle-x: num [1:52] 0.36 0.56 0.51 0.47 0.41 0.43 0.71 0.46 0.51 0.51 ...
$ hc-middle-y: num [1:52] 0.47 0.52 0.67 0.52 0.38 0.4 0.67 0.38 0.5 0.5 ...
$ hc-key : chr [1:52] "us-ma" "us-wa" "us-ca" "us-or" ...
$ hc-a2 : chr [1:52] "MA" "WA" "CA" "OR" ...
$ labelrank : chr [1:52] "0" "0" "0" "0" ...
$ hasc : chr [1:52] "US.MA" "US.WA" "US.CA" "US.OR" ...
$ woe-id : chr [1:52] "2347580" "2347606" "2347563" "2347596" ...
$ state-fips : chr [1:52] "25" "53" "6" "41" ...
$ fips : chr [1:52] "US25" "US53" "US06" "US41" ...
$ postal-code: chr [1:52] "MA" "WA" "CA" "OR" ...
$ name : chr [1:52] "Massachusetts" "Washington" "California" "Oregon" ...
$ country : chr [1:52] "United States of America" "United States of America" "United States of America" "United States of America" ...
$ region : chr [1:52] "Northeast" "West" "West" "West" ...
$ longitude : chr [1:52] "-71.99930000000001" "-120.361" "-119.591" "-120.386" ...
We must join the data in US_map with the data in state_df
This way, the plotting function knows what value must be assigned to what shape
We will use highcharters’ joinBy argument, a vector of 2 variable names, each of which should correspond to variables of the same values in both datasets
In our scenario, let’s use variables that identify the name of the state
These variables are:
name in the US_mapState in the state_df dataframe# Select columns to display on map.
data_for_map = select(state_df,
Population, #<- select `Population` to display as value on shape
State) #<- select `State` to join this data with map data
# Rename columns: `Population` -> `value`, because highcharts needs a column
# called `value` to attach it to shape.
colnames(data_for_map) = c("value", "State")
# Adjust data (divide population by 1000, to make units in millions).
data_for_map$value = data_for_map$value/1000
head(data_for_map) value State
1 3.615 Alabama
2 0.365 Alaska
3 2.212 Arizona
4 2.110 Arkansas
5 21.198 California
6 2.541 Colorado
Use continuous color palettes to indicate ranges of values from small to large
For example, we can use a range of colors generated based on the state population
Color codes (both RGB and hex) can be found on this link
Color palettes can also be created using the color_stops() function
data argument in the hc_add_series function to plot the columns from the cleaned datahc_colorAxis to add the color gradient for representing the population in different statesinteractive_population_map =
highchart(type = "map") %>%
hc_add_series(mapData = US_map,
data = data_for_map, #<- data to plot on shapes
name = "Population in 1975", #<- series name is `Population`
joinBy = c("name", #<- join by `name` property in `mapData`
"State") ) %>% #<- with `State` column in `data`
hc_colorAxis(min = min(data_for_map$value), #<- set colors: min value => minimum population
max = max(data_for_map$value), #<- max value => maximum population
minColor = "#CCCCFF", #<- min value color
maxColor = "#000066") #<- max value colorinteractive_population_map_adjusted = interactive_population_map %>%
hc_add_series(mapData = US_map,
data = data_for_map,
name = "Population in 1975 ",
joinBy = c("name",
"State"),
dataLabels = list(enabled = TRUE, #<- Add labels with the
format = # postal code of the state
'{point.properties.postal-code}')
) %>%
hc_tooltip(valueSuffix = " million") %>% #<- set value suffix
hc_mapNavigation(enabled = TRUE) %>% #<- Add zoom feature
hc_title(text = "US States Population in millions (1975)") #<- set plot title# Double click on area or use the `+` button to zoom in on an area.
# Use the `-` button to zoom out.
interactive_population_map_adjusted# Set working directory to where you save plots.
setwd(plot_dir)
# Save desired interactive plot to an HTML file.
saveWidget(interactive_population_map_adjusted, #<- plot object to save
"interactive_population_map.html", #<- name of file to where the plot is to be saved
selfcontained = TRUE) #<- set `selfcontained` to TRUE, so that
# all necessary files and scripts are embedded
# into the HTML file itself | Objective | Complete |
|---|---|
| Create interactive maps utilizing JSON files |
✔ |
| Illustrate adding motion to maps to display spatial data over time | |
| Discuss best practices for highcharter maps |
hc_motion() function# Set working directory to data_dir
setwd(data_dir)
# We can also load non-spatial data from a JSON file.
data_for_map = fromJSON("drug_overdose.json")
head(data_for_map) fips year value
1 01001 2002 1
2 01003 2002 2
3 01005 2002 0
4 01007 2002 1
5 01009 2002 2
6 01011 2002 0
Let’s create a list containing a data series for each year based on three sets of values from the dataset:
ds <- data_for_map %>%
group_by(fips) %>% #<- group by state
do(state_deaths = list( #<- go through each state
fips = first(.$fips), #<- select the FIPS for that state
sequence = .$value, #<- create a list of values for that state
value = first(.$value))) %>% #<- select the first value to initialize the map
.$state_deaths #<- put the three together in a list `state_deaths`The hc_motion function is commonly used to create dynamic and animated charts in highcharter, allowing you to visualize data changes over time or other sequential steps.
enabled (boolean): Enables or disables motion in the plot.axisLabel (string): Sets the label for the motion slider.labels (vector): Labels the animation steps (e.g., by year or time period).interactive_map_motion <- highchart(type = "map") %>%
hc_add_series(data = ds, #<- data to plot on shapes
name = "Drug deaths per 100,000", #<- series name
mapData = uscountygeojson, #<- map data from `highcharter`
joinBy = "fips", #<- join by `fips` field in `data` and `mapData`
borderWidth = 0.01) %>% #<- adjust border line for each shape
hc_colorAxis(stops = color_stops()) %>% #<- create a color legend
hc_title(text = "Drug Overdose Deaths per 100,000 between 2002 and 2014") %>%
hc_motion( #<- add motion
enabled = TRUE,
axisLabel = "year", #<- name of motion slider
labels = sort(unique(data_for_map$year)), #<- label the animation by year
)# Set working directory to where you save plots.
setwd(plot_dir)
# Save desired interactive plot to an HTML file.
saveWidget(interactive_map_motion, #<- plot object to save
"interactive_map_motion.html", #<- name of file to where the plot is to be saved
selfcontained = TRUE) #<- set `selfcontained` to TRUE, so that
# all necessary files and scripts are embedded
# into the HTML file itself | Objective | Complete |
|---|---|
| Create interactive maps utilizing JSON files |
✔ |
| Illustrate adding motion to maps to display spatial data over time |
✔ |
| Discuss best practices for highcharter maps |
Use motion to add dynamic time-series data to spatial data
To declutter a map that looks too busy:
You are now ready to try tasks 1-6 in the Exercise for this topic
| Objective | Complete |
|---|---|
| Create interactive maps utilizing JSON files |
✔ |
| Illustrate adding motion to maps to display spatial data over time |
✔ |
| Discuss best practices for highcharter maps |
|
In this part of the course, we have covered: